#!/bin/bash

readonly valid_resources=('blueutil' 'cpulimit' 'exiftool' 'ffmpeg' 'mediainfo' 'multimarkdown' 'youtubedl') # Keep in sync with resource functions
readonly shared_resources_id='com.vitorgalvao.alfred._sharedresources'
[[ -n "${alfred_workflow_data}" ]] || readonly alfred_workflow_data="$(mktemp -d)/Workflow Data/fake_workflow" # To prevent commands reliant on this variable from breaking when testing outside a Workflow
readonly shared_resources_dir="$(dirname "${alfred_workflow_data}")/${shared_resources_id}"
readonly shared_resources_bin="${shared_resources_dir}/bin"
readonly PATH="/opt/homebrew/bin:/usr/local/bin:${shared_resources_bin}:${PATH}"
readonly arch="$(/usr/bin/arch)"

function renew_bin {
  local -r bin_name="${1}"
  local -r expire_days="${2}"
  local -r bin_path="$(command -v "${bin_name}")"

  # If binary is not found, renew (download to shared directory)
  [[ -n "${bin_path}" ]] || return 0

  # If `expire_days` is `never`, do not renew (keep everything as is)
  [[ "${expire_days}" == 'never' ]] && return 1

  # If binary is in shared directory and older than set days, renew (redownload)
  [[ "${bin_path}" == *"${shared_resources_id}"* && "$(find "${bin_path}" -mtime "+${expire_days}")" ]] && return 0

  # Otherwise, do not renew (keep everythin as is)
  return 1
}

function is_string_in_array {
  local -r string="${1}"

  for value in "${@:2}"; do
    [[ "${string}" == "${value}" ]] && return 0
  done

  return 1
}

function curl_error {
  echo "Could not download ${1}." >&2
  exit 1
}

function ensure_resources_dir {
  [[ -d "${shared_resources_bin}" ]] || mkdir -p "${shared_resources_bin}"
}

function mount_dmg {
  local -r dmg_path="${1}"
  local -r plist="$(mktemp)" # We need to make the plist into a file so PlistBuddy will read it

  hdiutil mount -plist -nobrowse -readonly -mountrandom "$(mktemp -d)" "${dmg_path}" > "${plist}"

  local -r dicts="$(/usr/libexec/PlistBuddy -c 'print system-entities' "${plist}" | grep --count 'Dict')"

  for i in $(seq 0 "$(bc <<< "${dicts} - 1")") ; do
    /usr/libexec/PlistBuddy -c "print system-entities:${i}:mount-point" "${plist}" 2>/dev/null
  done
}

function unmount_dmg {
  hdiutil unmount "${1}" > /dev/null
}

# Resource functions
function blueutil_getter {
  # Manually change
  local -r bin_name='blueutil'
  renew_bin "${bin_name}" '90' || return

  local -r bin_version='2.9.0'
  local -r bin_sha="$([[ "${arch}" == 'i386' ]] && echo '429703e2bae1445d2a6ae2e1f52ed2c1f0bad3a94e80b44bfe36e698ba5ded30' || echo 'e29ddccdf7253406a3685f4099f3424ffb6d399ff2643f2d79f281ad97b93a67')"

  # Consistent over Hombrew installs
  ensure_resources_dir
  local -r extract_dir="$(mktemp -d)"
  local -r bin_path="${shared_resources_bin}/${bin_name}"
  local -r bin_url="https://ghcr.io/v2/homebrew/core/${bin_name}/blobs/sha256:${bin_sha}"

  if curl --silent --location --header 'Authorization: Bearer QQ==' "${bin_url}" | tar xC "${extract_dir}"; then
    mv "${extract_dir}/${bin_name}/${bin_version}/bin/${bin_name}" "${bin_path}"
    chmod +x "${bin_path}"
  else
    curl_error "${bin_name}"
  fi

  rm -rf "${extract_dir}"
}

function cpulimit_getter {
  # Manually change
  local -r bin_name='cpulimit'
  renew_bin "${bin_name}" '90' || return

  local -r bin_version='0.2'
  local -r bin_sha="$([[ "${arch}" == 'i386' ]] && echo 'f3f394e17febb7af49a1cb35c46e33856263dc58016d959aad2d2a250aae1d7d' || echo 'f09919436a14d7b1598720ca832435b2500aebe0839f5055a253f52c59642a5d')"

  # Consistent over Hombrew installs
  ensure_resources_dir
  local -r extract_dir="$(mktemp -d)"
  local -r bin_path="${shared_resources_bin}/${bin_name}"
  local -r bin_url="https://ghcr.io/v2/homebrew/core/${bin_name}/blobs/sha256:${bin_sha}"

  if curl --silent --location --header 'Authorization: Bearer QQ==' "${bin_url}" | tar xC "${extract_dir}"; then
    mv "${extract_dir}/${bin_name}/${bin_version}/bin/${bin_name}" "${bin_path}"
    chmod +x "${bin_path}"
  else
    curl_error "${bin_name}"
  fi

  rm -rf "${extract_dir}"
}

function exiftool_getter {
  local -r bin_name='exiftool'
  renew_bin "${bin_name}" '90' || return

  ensure_resources_dir
  local -r extract_dir="$(mktemp -d)"
  local -r bin_path="${shared_resources_bin}/${bin_name}"
  local -r lib_dir="${shared_resources_dir}/${bin_name}"
  local -r latest_tag="$(curl --silent "https://api.github.com/repos/exiftool/${bin_name}/tags" | grep 'tarball_url' | head -1 | sed -E 's/.*: "(.*)".*/\1/')"

  if curl --location --silent "${latest_tag}" | tar xC "${extract_dir}"; then
    mv "${extract_dir}/"* "${lib_dir}"
    ln -s "${lib_dir}/${bin_name}" "${bin_path}"
  else
    curl_error "${bin_name}"
  fi

  rm -rf "${extract_dir}"
}

function ffmpeg_getter {
  local -r bin_name='ffmpeg'
  renew_bin "${bin_name}" '90' || return

  ensure_resources_dir
  local -r extract_dir="$(mktemp -d)"
  local -r bin_path="${shared_resources_bin}/${bin_name}"

  if curl --silent --location --no-buffer "https://evermeet.cx/${bin_name}/get/zip" | ditto -xk - "${extract_dir}"; then
    mv "${extract_dir}/${bin_name}" "${bin_path}"
  else
    curl_error "${bin_name}"
  fi

  rm -rf "${extract_dir}"
}

function mediainfo_getter {
  local -r bin_name='mediainfo'
  renew_bin "${bin_name}" '90' || return

  ensure_resources_dir
  local -r bin_path="${shared_resources_bin}/${bin_name}"
  local -r file_name="$(curl --silent "https://mediaarea.net/en/MediaInfo/Download/Mac_OS" | grep 'CLI.*\.dmg' | head -1 | sed -E 's/.*<td><a href="([^"]+)".*/\1/')"
  local -r dmg="$(mktemp)"
  local -r pkg_extract="$(mktemp -d)"

  if curl --silent --output "${dmg}" "https:${file_name}"; then
    local -r dmg_mount_point="$(mount_dmg "${dmg}")"
    cd "${pkg_extract}" || exit 1
    xar -xf "${dmg_mount_point}/${bin_name}.pkg"
    gunzip --decompress --stdout 'Payload' | cpio -i 2> /dev/null
    cp "./usr/local/bin/${bin_name}" "${bin_path}"
    unmount_dmg "${dmg_mount_point}"
    cd - > /dev/null || exit 1
    rm -rf "${dmg}" "${pkg_extract}"
  else
    curl_error "${bin_name}"
  fi
}

function multimarkdown_getter {
  # Manually change
  local -r bin_name='multimarkdown'
  renew_bin "${bin_name}" '90' || return

  local -r bin_version='6.6.0'
  local -r bin_sha="$([[ "${arch}" == 'i386' ]] && echo '15b87bf8b7be554761d0114af63d3789df6db6cb58616afc408f569ea8ac50d0' || echo 'c377c5976fff15a469b330470febc8b7db8f695b597e588fd35e975fe17010a5')"

  # Consistent over Hombrew installs
  ensure_resources_dir
  local -r extract_dir="$(mktemp -d)"
  local -r bin_path="${shared_resources_bin}/${bin_name}"
  local -r bin_url="https://ghcr.io/v2/homebrew/core/${bin_name}/blobs/sha256:${bin_sha}"

  if curl --silent --location --header 'Authorization: Bearer QQ==' "${bin_url}" | tar xC "${extract_dir}"; then
    mv "${extract_dir}/${bin_name}/${bin_version}/bin/${bin_name}" "${bin_path}"
    chmod +x "${bin_path}"
  else
    curl_error "${bin_name}"
  fi

  rm -rf "${extract_dir}"
}

function youtubedl_getter {
  local -r bin_name='youtube-dl'
  renew_bin "${bin_name}" '15' || return

  if youtube-dl --update --quiet; then
    touch "$(command -v 'youtube-dl')"
    return
  fi

  ensure_resources_dir
  local -r bin_path="${shared_resources_bin}/${bin_name}"

  if curl --silent --location 'https://yt-dl.org/downloads/latest/youtube-dl' --output "${bin_path}"; then
    chmod +x "${bin_path}"
  else
    curl_error "${bin_name}"
  fi
}

for argv in "${@}"; do
  resources_to_use+=("${argv}")
done

# Check if arguments are valid
for resource in "${resources_to_use[@]}"; do
  if ! is_string_in_array "${resource}" "${valid_resources[@]}"; then
    echo "
      Could not recognise argument ${1}. It needs to be one or more of:
        $(printf "\n  %s" "${valid_resources[@]}")
    " | sed -E 's/^ {6}//' >&2

    exit 1
  fi
done

# Get resources
for resource in "${resources_to_use[@]}"; do
  "${resource}_getter" # Run the function to get the tool. '_getter' is required as otherwise the function will detect itself when running 'command'
done

echo -n "${PATH}"
